#ifndef _RSC_RECORD_H_
#define _RSC_RECORD_H_

#include <pthread.h>
#include <unistd.h>


/**************************** DataType Declarations *************************/
/** AVSampleFormat  */
enum record_sample_format 
{
    REC_SAMPLE_FMT_NONE = -1,
    REC_SAMPLE_FMT_U8,          ///< unsigned 8 bits
    REC_SAMPLE_FMT_S16,         ///< signed 16 bits
    REC_SAMPLE_FMT_S32,         ///< signed 32 bits
    REC_SAMPLE_FMT_FLT,         ///< float
    REC_SAMPLE_FMT_DBL,         ///< double

    REC_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
    REC_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
    REC_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
    REC_SAMPLE_FMT_FLTP,        ///< float, planar
    REC_SAMPLE_FMT_DBLP,        ///< double, planar

    REC_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
};

/** record parameters define */
enum record_codec_format
{
	REC_CODEC_H264,
	REC_CODEC_MJPEG,
	REC_CODEC_AAC,
	REC_CODEC_PCM_ALAW,
	REC_CODEC_MAX
};
enum record_pack_format
{
	REC_PACK_AVI,
	REC_PACK_WAV,
	REC_PACK_MP3,
	REC_PACK_MAX
};
enum record_mode
{
	REC_MODE_UNDEF = 0,
	REC_MODE_AUTO, /* record when poweroff */
	REC_MODE_TIMER, /* timing record,assign start and end time */
	REC_MODE_EVENT, /* event trigger record,such open-door ,alarm event */
	REC_MODE_CYCLE, /* record plan mode,day,week,month or year plan */
};
enum record_data_type
{
	REC_DTYPE_VIDEO,
	REC_DTYPE_AUDIO,
	REC_DTYPE_META,
	REC_DTYPE_MAX
};

enum record_status_machine
{
	REC_STAT_INIT,
	REC_STAT_CHECK, /* check params */
	REC_STAT_PREPARE,
	REC_STAT_WRITE,
	REC_STAT_FINI,
	REC_STAT_EXIT, /* exit record routine */
};

typedef struct record_mode_param
{
	time_t timer_start; 
	time_t timer_end;

	int event_trigger;/* set to 1 when event happen */
	int event_time; /* event record time length,unit second */
	char event_desc[16];/* event description ,such as "alarm" */

	/* cycle plan record, 0 is not set,indicates every 'unit' */
	int cycle_time; /* record time length,unit second */
	int cycle_hour; /* 1-24 hour, 0 -- every hour,the following is same */
	int cycle_day;/* 1-31 day every month ,mutual with @cycle_week@,has high priority */
	int cycle_week;/* 1-7 weekday every month */
	int cycle_month; /* 1-12 month every year */
	int cycle_year; /* 2000 - year */
}st_rec_mode_param;

typedef struct record_media_param
{
	/** video param */
	unsigned int video_cbr; /** cbr: 1, vbr: 0 */
	unsigned int video_bitrate;
	unsigned int video_framerate;
	unsigned int video_gop;
	unsigned int video_codec; /* see enum record_codec_format */
	unsigned int video_width;
	unsigned int video_height;
	unsigned int pic_level; /* picture level: 1-5, low to high */
	/** audio param */
	unsigned int audio_sample_fmt; /* see @enum record_sample_format@ */
	unsigned int audio_sample_rate; /* unit is HZ ,such as value 44100 */
	unsigned int audio_channels; /* perhaps value: 1,2,3 */
	unsigned int audio_bitrate;
	unsigned int audio_codec; /* see enum record_codec_format */
}st_rsc_rec_media;

#define RSC_REC_MAX_CHN 7
typedef struct record_control_param
{
	int on;
	int file_time; /* record file time ,unit is second */
	int file_pack ;/* pack format,such avi */
	char file_format[64];/* filename format string,such as 'YYYYMMDD/hhmmss_nn.avi' */

	int audio_on;/* whether to record audio */
	int audio_solo;/* whether to record audio to a solo file */
	int audio_time;/* audio solo file time when @audio_solo is on,unit is second */
	int audio_pack; /* audio pack format when @audio_solo is on,such wav */ 
	
	int mode;
	char mode_desc[16]; /* mode description,such as 'auto','event','cycle' .etc */
	st_rec_mode_param mode_param;
}st_rsc_rec_ctrl;

/* frame data structure to record */
struct record_frame_info
{
	unsigned char *addr;
	unsigned int size; /* addr availabe size */
	unsigned int len; /* frame length */
	unsigned long pts;
	unsigned int flag; 
};

typedef struct record_data_source
{
	/** data source */
	int chn; /* every channel has a data source for each data-type */
	int parallel; /* if use parallel record method (multi-pthread) */
	unsigned char *video_ds[RSC_REC_MAX_CHN];
	unsigned char *audio_ds[RSC_REC_MAX_CHN];
	unsigned char *meta_ds[RSC_REC_MAX_CHN];
	/** callback functions */
	int (*preprocess[REC_DTYPE_MAX])(struct record_frame_info *frame,unsigned char *source);
	int (*postprocess[REC_DTYPE_MAX])(unsigned char *outpool,struct record_frame_info *frame);
}st_rsc_rec_data;

struct rsc_record_param
{
	pthread_rwlock_t lock; /** sync the access to global params */
	st_rsc_rec_media media;
	st_rsc_rec_ctrl  control;
	st_rsc_rec_data  source;
};

/** Channel Specific Parameters which have higher priority than global params */
struct rsc_channel_param
{
	int valid; /** set true to use channel param,default is false */
	st_rsc_rec_media media;
	st_rsc_rec_ctrl  control;
};

/** Only Used in the RSC Internal */
struct record_context_info
{
	int cur_chn;
	char filepath[64]; /* record mode absolute path */
	char filename[64]; /*  relative path file name */
	void *context[RSC_REC_MAX_CHN]; /* context info, such as ffmpeg context info. */
};


/**************************** Function Declarations *************************/
int rsc_get_rec_params(struct rsc_record_param *param);
int rsc_set_rec_params(struct rsc_record_param *param);

int rsc_start_record(void);
int rsc_stop_record(void);

/// Record Init and Exit APIs
int rsc_init_record(struct rsc_record_param *param);
void rsc_exit_record(void);

#endif

